﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using Newtonsoft.Json;

namespace Missbot.Common.Net
{
    public class HttpRequestor
    {
        private static ILogSvc ILogSvc => AutofacSvc.Resolve<ILogSvc>();

        /// <summary>
        /// 向指定接口发送get请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="paramDic">参数列表</param>
        /// <param name="cookies"></param>
        /// <returns></returns>
        public static ResultType GetData<ResultType>(string url, Dictionary<string, string> paramDic = null, CookieModel[] cookies = null)
        {
            var result = GetData(url, paramDic, cookies);
            return string.IsNullOrEmpty(result) ? default : JsonConvert.DeserializeObject<ResultType>(result);
        }

        public static string GetData(string url, Dictionary<string, string> paramDic = null, CookieModel[] cookies = null)
        {
            var param = paramDic == null
                            ? string.Empty
                            : $"?{string.Join("&", paramDic.Select(dic => $"{dic.Key}={HttpUtility.UrlEncode(dic.Value)}"))}";

            var req = (HttpWebRequest)WebRequest.Create($"{url}{param}");
            req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
            // 设置Cookie
            if (cookies != null)
            {
                req.CookieContainer = new CookieContainer();
                foreach (var cookieModel in cookies)
                {
                    var cookie = new Cookie(cookieModel.CookieKey, cookieModel.CookieValue)
                    {
                        Expires = DateTime.Now.AddDays(1),
                        Domain = cookieModel.Domain,
                        Path = cookieModel.Path
                    };
                    req.CookieContainer.Add(cookie);
                }
            }

            try
            {
                var resp = (HttpWebResponse)req.GetResponse();
                if (!resp.ContentType.Contains("json"))
                {
                    return default;
                }

                using var stream = resp.GetResponseStream();
                if (stream == null)
                {
                    return default;
                }

                //获取内容
                using var reader = new StreamReader(stream);
                var result = reader.ReadToEnd();
                return result;
            }
            catch (Exception e)
            {
                ILogSvc.LogError(e, new { url, paramDic, cookies });
                return default;
            }
        }

        /// <summary>
        /// 向指定接口post数据
        /// </summary>
        /// <typeparam name="ResultType">返回值反序列化类型</typeparam>
        /// <param name="interfaceName">接口地址</param>
        /// <param name="data">数据</param>
        /// <param name="timeout">超时时间(秒)</param>
        /// <returns></returns>
        public static ResultType PostData<ResultType>(string interfaceName, object data, int timeout = 100) where ResultType : class
        {
            ResultType _reqRet;
            try
            {
                var postData = JsonConvert.SerializeObject(data);
                var bytes = Encoding.UTF8.GetBytes(postData);

                var request = (HttpWebRequest)WebRequest.Create(interfaceName);
                request.Method = "POST";
                request.ContentType = "application/json; charset=utf-8";
                request.Timeout = timeout * 1000;
                request.ContentLength = bytes.Length;

                request.GetRequestStream().Write(bytes, 0, bytes.Length);
                using var response = (HttpWebResponse)request.GetResponse();
                var respStream = response.GetResponseStream();
                if (respStream == null)
                {
                    return default;
                }

                using var streamReader = new StreamReader(respStream);
                var responseString = streamReader.ReadToEnd();
                _reqRet = JsonConvert.DeserializeObject<ResultType>(responseString);
            }
            catch (Exception e)
            {
                ILogSvc.LogError(e, new { interfaceName, data });
                return default;
            }

            return _reqRet;
        }
    }
}